'use strict';

var debug = require('debug'),
  log = debug('yozh:mw:log'),
  error = debug('yozh:mw:error'),
  verbose = debug('yozh:mw:verbose'),
  uuid = require('uuid'),
  roleService = require('../modules/role/role.service'),
  tools = require('../lib/tools'),
  config = require('../config/config'),
  respData = require('../config/json_resp_data');

/**
 * permission middleware
 * @param  {Object} opts options
 * @return {Function} ES6 generator function
 */
module.exports = function(opts) {
  var middleware = function *permission(next) {
    if (config.skipPath.indexOf(this.path) > -1) {
      log('skip token middleware, path: ' + this.path);
      return yield next;
    }
    // if (this.state.skipChectToken) {
    //   log('skip permission middleware.');
    //   return yield next;
    // }
    // this.state.token = tools.getToken(this.header);
    var links = respData.createSimpleLinks(this.path);

    var errorId = uuid.v4();
    var errors = respData.createErrors(
      errorId,
      405,
      '01001',
      '',
      '',
      {
        method: this.request.method,
        clentIp: this.ip,
        path: this.path,
        querystring: this.query
      }
    );

    if (this.state.token || tools.getAccessToken(this.header)) {
      // get token
      if (this.state.token) {
        this.state.token = tools.getAccessToken(this.header);
      }
      var role = yield roleService.findByIdWithMenuOperator(
        this.state.token.roleId
      );
      if (role) {
        var search
          = config.constants.article + '|' +
            config.constants.base + '|' +
            config.constants.log + '|' +
            config.constants.menu + '|' +
            config.constants.operator + '|' +
            config.constants.part + '|' +
            config.constants.relation + '|' +
            config.constants.role + '|' +
            config.constants.topic + '|' +
            config.constants.user;
        var reg = new RegExp(search);
        var purview = role.purview;
        for (var i = 0; i < purview.length; i ++) {
          if (purview[i].menu && reg.test(purview[i].menu.action)) {
            if (purview[i].operatorList) {
              var operators = '';
              for (var j = 0; j < purview[i].operatorList.length; j ++) {
                if (operators === '') {
                  operators += purview[i].operatorList[j].action + '|';
                } else {
                  operators += purview[i].operatorList[j].action;
                }
              }
              if (operators !== '') {
                var sreg = new RegExp(operators);
                if (sreg.test(this.require.method)) {
                  yield next;
                } else {
                  // this.throw(405, 'Request Method Not Allowed\n');
                  // this.body = 'Request Method Not Allowed';
                  errors.detail = '当前用户不允许访问方法';
                  errors.source = 'Method Not Allowed';
                  this.body = JSON.stringify({links: links, errors: errors});

                  return this.status = 405;
                }
              } else {
                // this.throw(405, 'Not Allowed any method\n');
                // this.body = 'Not Allowed any method';
                errors.detail = '不允许访问任何方法';
                errors.source = 'Not Allowed Any Method';
                this.body = JSON.stringify({links: links, errors: errors});

                return this.status = 405;
              }
            } else {
              // this.throw(405, 'Not Allowed any method\n');
              // this.body = 'Not Allowed any method';
              errors.detail = '不允许访问任何方法';
              errors.source = 'Not Allowed Any Method';
              this.body = JSON.stringify({links: links, errors: errors});
              return this.status = 405;
            }
          } else {
            // this.throw(405, 'Request Module Not Allowed\n');
            // this.body = 'Request Module Not Allowed';
            errors.detail = '不允许访问该模块';
            errors.source = 'Module Not Allowed';
            this.body = JSON.stringify({links: links, errors: errors});
            return this.status = 405;
          }
        }
      } else {
        // this.throw(405, 'Permission Error\n');
        this.body = 'Permission Error';
        return this.status = 405;
      }
    } else {
      // this.throw(401, 'Authorization Error\n');
      this.body = 'Authorization Error';
      return this.status = 401;
    }
  };
  return middleware;
};
